맨위로가기

2038년 문제

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

2038년 문제는 많은 컴퓨터 시스템에서 시간과 날짜를 표현하기 위해 사용하는 유닉스 시간이 2038년 1월 19일 03시 14분 07초 (UTC) 이후에 정수 오버플로우로 인해 오류를 일으키는 문제이다. 이는 유닉스 시간이 부호 있는 32비트 정수로 인코딩되어 표현 가능한 최대 시간을 초과하기 때문이다. 이 문제를 해결하기 위해 64비트 시스템으로 전환하거나, time_t를 부호 없는 32비트 정수형으로 변경하는 등의 해결책이 제시되었으며, 운영체제 및 소프트웨어별로 64비트 time_t 지원이 진행되고 있다.

더 읽어볼만한 페이지

  • 미래 문제 - 초화산
    초화산은 1,000 km³ 이상의 분출물을 내뿜는 대규모 폭발성 화산으로, 토바 호, 옐로스톤, 라 가리타 칼데라 등이 대표적인 사례이며 지구 기후와 생태계에 막대한 영향을 미치고 전 세계적인 사회경제적 붕괴를 야기할 수 있다는 우려가 존재한다.
  • 미래 문제 - 인공 일반 지능의 실존적 위험
    인공 일반 지능의 실존적 위험은 인간을 초월하는 AGI가 인류를 통제 불가능하게 만들 위험을 의미하며, 이는 AGI 통제의 어려움, 지능 폭발, 인류의 이익을 고려하지 않을 가능성에서 비롯된다.
  • 유닉스 - 유닉스 시간
    유닉스 시간은 1970년 1월 1일 00:00:00 UTC부터 경과된 초를 나타내는 시스템으로, 컴퓨터 시스템에서 시간 저장 및 처리에 널리 사용되며 32비트 정수 표현 시 2038년 문제를 야기할 수 있고 64비트 정수로 해결 가능하며, 다양한 시스템에서 타임스탬프로 활용되지만 윤초 처리 차이로 UTC 시간과 완벽히 일치하지는 않는다.
  • 유닉스 - 유닉스 계열
    유닉스 계열은 유닉스 운영체제의 특징과 설계를 공유하는 운영체제들을 지칭하며, 유전적, 상표, 기능적 유닉스로 분류되고 macOS는 상표 유닉스이자 유전적 유닉스에 해당하며 리눅스는 기능적 유닉스의 대표적인 예이다.
2038년 문제
개요
이름2038년 문제
다른 이름유닉스 밀레니엄 버그 (Unix Millennium bug)
Y2K38
설명1970년 1월 1일 0시 0분 0초 UTC부터 시작하여 2,147,483,647 (2³¹ − 1)초가 경과하는 시점인 2038년 1월 19일 3시 14분 7초 UTC에 발생하는 컴퓨터 소프트웨어 버그이다.
원인일부 시스템에서 시간을 32비트 부호 있는 정수로 저장하기 때문에 발생하는 문제이다. 이 정수는 1970년 1월 1일 이후의 시간을 초 단위로 나타낸다. 2,147,483,647초를 초과하면 오버플로가 발생하여 1901년 12월 13일 또는 2106년 2월 7일과 같은 과거 날짜로 되돌아갈 수 있다.
기술적 세부 사항
표현 방식32비트 부호 있는 정수
기준 시점1970년 1월 1일 0시 0분 0초 UTC
오버플로 발생 시점2038년 1월 19일 3시 14분 7초 UTC
오버플로 발생 값2,147,483,647 (2³¹ − 1)
영향
영향 받는 시스템32비트 시스템, 임베디드 시스템, 데이터베이스, 소프트웨어 애플리케이션 등
잠재적 문제시스템 오작동, 데이터 손상, 서비스 중단 등
해결 방안
주요 해결책64비트 정수 사용으로 전환
기타 해결책다른 시간 표현 방식 사용
윤년 문제와 유사한 임시 해결책 적용
역사적 맥락
유사한 문제Y2K 문제
Y2K 문제와의 차이점Y2K 문제는 날짜 표기 방식의 문제였지만, 2038년 문제는 데이터 유형의 한계로 인한 문제이다.
진행 상황
현재 상황많은 시스템이 이미 64비트 시스템으로 전환되었지만, 여전히 32비트 시스템을 사용하는 시스템이 존재한다.
예상되는 영향2038년 1월 19일 이후에도 32비트 시스템을 사용하는 시스템에서 문제가 발생할 수 있다.

2. 원인

유닉스 시간은 많은 컴퓨터 시스템에서 시간을 나타내는 방식으로, 1970년 1월 1일 00:00:00 UTC 이후 경과한 초 수로 표현된다. 이를 "유닉스 에포크"라고 한다.[4]

전통적으로 유닉스 시간은 부호 있는 32비트 정수로 표현되었는데, 이 방식은 2038년 1월 19일 03:14:07 UTC 이후의 시간을 표현할 수 없다. 이 시간이 지나면 정수 오버플로가 발생하여 시간이 1901년으로 돌아가는 문제가 발생한다.

2000년 문제가 응용 프로그램 수준에서 수정 가능했던 것과 달리, 2038년 문제는 시스템의 더 깊은 층위에 있어 해결하기 더 어렵다는 지적이 있다.[41]

2038년 문제와 유사한 문제는 2004년에 ATM 오작동 등의 형태로 이미 나타난 적이 있는데,[40] 이는 프로그램 내부에서 시간 계산 시 오버플로가 발생했기 때문이다.

2. 1. 32비트 정수 표현의 한계

많은 컴퓨터 시스템은 시간을 측정하기 위해 유닉스 시간을 사용하는데, 이는 1970년 1월 1일 00:00:00 UTC(유닉스 에포크) 이후 경과한 초를 나타내는 국제 표준이다.[4]

유닉스 시간은 전통적으로 부호 있는 32비트 정수로 표현되어 왔다. '부호 있는'이란 양수, 음수, 0을 모두 나타낼 수 있음을 의미하며, 2의 보수 형식을 사용한다. 부호 있는 32비트 정수는 −(231)에서 231 − 1 (2,147,483,647)까지의 값만 표현할 수 있다. 따라서 유닉스 시간을 저장하는 데 32비트 정수를 사용하면, 표현 가능한 가장 늦은 시간은 2,147,483,647초 뒤인 2038년 1월 19일 03:14:07 UTC가 된다.[5]

이 값을 1초 증가시키면 정수 오버플로가 발생하여 부호 비트가 뒤집혀 음수가 된다. 이는 시간을 1901년 12월 13일 금요일 20:45:52로 잘못 해석하게 만든다.

UNIX 및 UNIX 파생 운영체제의 많은 부분은 C 언어로 작성되었으며, 시간을 표현하는 "time_t 유형"을 사용한다. C 언어 표준은 `time_t` 유형의 범위와 정밀도를 구현에 따라 다르게 정의한다.[39] 전통적인 구현에서는 `time_t`를 부호 있는 32비트 정수형으로 사용했기 때문에, 2038년 1월 19일 3시 14분 7초 (한국 표준시에서는 2038년 1월 19일 12시 14분 7초)를 넘으면 오버플로가 발생한다.

2. 2. 정수 오버플로우

많은 컴퓨터 시스템은 디지털 시간 기록을 위한 국제 표준인 유닉스 시간을 사용하여 시간과 날짜를 측정한다. 유닉스 시간은 1970년 1월 1일 00:00:00 UTC 이후 경과한 초의 수로 정의되며, 이는 "유닉스 에포크"라고 불린다.[4]

유닉스 시간은 역사적으로 부호 있는 32비트 정수로 인코딩되어 왔으며, 이는 정수 값을 나타내는 32개의 비트로 구성된 데이터 형식이다. '부호 있는'은 숫자가 양수, 음수 및 0을 모두 나타낼 수 있음을 의미하며, 일반적으로 2의 보수 형식으로 저장된다. 따라서 부호 있는 32비트 정수는 −(231)에서 2,147,483,647 (231 − 1)까지의 정수 값만 나타낼 수 있다. 결과적으로, 부호 있는 32비트 정수가 유닉스 시간을 저장하는 데 사용되는 경우, 저장할 수 있는 가장 늦은 시간은 에포크 이후 2,147,483,647초이다.[5] 이 값을 1초 더 증가시켜 에포크 이후 231초(03:14:08)로 만들려고 시도하는 시스템은 정수 오버플로가 발생하여 부호 비트가 의도치 않게 뒤집혀 음수를 나타낸다. 이렇게 하면 정수 값이 −(231) 또는 에포크 ''이후''가 아닌 ''이전'' 231초로 변경되어 시스템은 1901년 12월 13일 금요일 20:45:52로 해석한다. 여기서부터 시스템은 0을 향해 계속 카운트하고, 다시 양의 정수를 통해 카운트한다. 많은 컴퓨터 시스템이 중요한 기능을 실행하기 위해 시간 계산을 사용하므로, 이 버그는 심각한 문제를 야기할 수 있다.

UNIX 및 UNIX 파생 운영체제 (OS)의 핵심 소프트웨어 부품의 상당수는 C 언어로 작성되었는데, 앞서 언급한 경과 초를 표현하는 유형은 현재 표준에서는 "time_t 유형"이다. C 언어의 표준인 "ISO/IEC 9899:1999"에서는 `time_t` 유형의 범위와 정밀도는 모두 구현 정의로 한다.[39] UNIX의 표준 (POSIX)에는 "shall be integer or real-floating types."라고만 기술되어 있으며, 비트 폭 및 값의 범위에 대해서는 아무런 규정도 없다.

전통적인 구현에서는 `time_t`를 `int` 또는 `long`의 typedef에 의한 유형 별칭(별칭)으로 하여, 그 유형은 부호 있는 32비트 정수형이었다. 이 때문에 최대값은 (231 − 1) = 2,147,483,647이 되어, 처리할 수 있는 것은 2,147,483,647초(≒ 68년)까지로 제한되어 있었다. 이를 전제로 작성된 프로그램은 협정 세계시 1970년 1월 1일 0시 0분 0초 (한국 표준시에서는 1970년 1월 1일 9시 0분 0초)부터 2,147,483,647초가 경과한 2038년 1월 19일 3시 14분 7초 (한국 표준시에서는 2038년 1월 19일 12시 14분 7초, 윤초는 고려하지 않음)를 넘으면 이 값이 오버플로된다. 만약 시각을 올바르게 처리하고 있다는 것을 전제로 한 코드가 있다면 오작동한다.

이 기한 이전에도 프로그램에서 내부적으로 이 제한을 초과하는 시각 데이터를 처리하려고 하면 유사한 오류가 발생하기 때문에, 예를 들어 정확히 절반이 경과한 2004년 1월 11일에는 이미 ATM의 오작동과 같은 문제가 발생했다.[40]

시간 a와 시간 b의 정확히 중간 시간을 구할 때, 각 유닉스 시간을 Ta와 Tb라고 하면, (Ta + Tb) / 2로 계산하면 2038년 문제의 절반 이후가 경과했을 경우 Ta + Tb 계산에서 오버플로가 발생하여 잘못된 결과가 나온다. 이는 1,073,741,824초째인 2004년 1월 10일 13시 37분 4초 이후가 이 경우에 해당한다. 2004년 1월 10일 또는 11일에 이 사례로 추정되는 보고가 있었다.[50] 이 문제를 회피하기 위해서는 계산 방법을 고안할 필요가 있다. 예를 들어, 시간의 중간을 구할 때, 오버플로를 피하기 위해 다음과 같은 방법이 생각할 수 있다.

  • '''시간의 차이를 계산한다''': 우선, 시간 b에서 시간 a를 빼서 그 차이를 구한다.
  • '''차이의 절반을 구한다''': 구한 차이를 2로 나눈다.
  • '''시간 a에 더한다''': 마지막으로, 시간 a에 차이의 절반을 더하여 중간 시간을 구한다.


이 방법을 수식으로 나타내면 다음과 같다: 중간 시간 = ''Ta'' + (''Tb'' − ''Ta'')/2

3. 취약 시스템

32비트 부호 있는 시간 표현을 사용하는 자료 구조를 사용하는 모든 시스템은 2038년 문제가 발생할 위험이 있다. 이러한 자료 구조에는 다음이 포함되지만, 이에 국한되지는 않는다.


  • 아이노드에서 시간을 나타내기 위해 32비트를 사용하는 파일 시스템
  • 32비트 시간 필드를 가진 바이너리 파일 형식
  • 32비트 시간 필드를 가진 데이터베이스
  • `UNIX_TIMESTAMP()`와 유사한 명령을 가진 SQL과 같은 데이터베이스 쿼리 언어


파일 시스템, 데이터베이스에 대한 더 자세한 내용은 하위 섹션을 참고할 수 있다.

임베디드 시스템은 계산이나 진단 로깅에 날짜를 사용하는 경우 2038년 문제의 영향을 받을 가능성이 높다.[6] 임베디드 시스템은 구성 요소로 사용되는 기계의 수명 동안 사용하도록 설계되며, 2038년에도 여전히 사용될 수 있는 시스템이 있을 수 있다. 이러한 시스템의 소프트웨어를 업그레이드하는 것은 비실용적이거나 불가능할 수 있으며, 32비트 제한을 수정하려면 교체가 필요할 수 있다.

안티록 브레이크 시스템(ABS), 전자 제어 주행 안정화 장치(ESC/ESP) 등을 포함하는 자동차 시스템, 관성 항법 장치 및 GPS 수신기를 사용하는 항공기 등 많은 운송 시스템이 임베디드 시스템을 광범위하게 사용한다.

하지만 모든 임베디드 시스템이 2038년 문제의 영향을 받는 것은 아니다. 날짜에 접근할 필요가 없는 시스템도 많으며, 날짜에 접근하더라도 절대적인 시간/날짜가 아닌 시간/날짜 간의 차이만 추적하는 시스템은 계산 특성상 큰 문제를 겪지 않을 것이다. 이것은 캘리포니아 대기 자원 위원회(CARB)와 같은 법률에 의해 규정된 표준에 기반한 자동차 진단의 경우이다.[8]

임베디드 시스템 및 안드로이드 운영체제에 대한 더 자세한 내용은 하위 섹션을 참고할 수 있다.

3. 1. 파일 시스템

32비트 부호 있는 시간 표현을 사용하는 자료 구조를 쓰는 모든 시스템은 실패할 위험이 있다. 특히 유닉스 시간을 사용하는 시스템에서 이 문제가 발생할 수 있다. 유닉스 시간은 협정 세계시로 1970년 1월 1일 0시 0분 0초부터 경과한 초를 나타내는데[39], 32비트 정수형으로는 2038년 1월 19일 3시 14분 7초(한국 표준시로는 2038년 1월 19일 12시 14분 7초)까지만 표현할 수 있다. 이 시간을 넘으면 오버플로가 발생하여 시간이 음수로 처리되거나 오작동을 일으킬 수 있다.

아이노드에서 시간을 나타내기 위해 32비트를 사용하는 파일 시스템이 대표적인 예이다. 예를 들어, Linux의 ext2, ext3, ReiserFS 파일 시스템의 타임 스탬프는 2038년 1월 19일까지만 지원한다.

2004년 1월 11일에는 일부 ATM에서 이와 유사한 문제가 발생한 적이 있다.[40] 이는 프로그램 내부에서 두 시각의 중간 시각을 계산할 때 산술 평균을 잘못 사용했기 때문이다.

3. 2. 데이터베이스

32비트 부호 있는 시간 표현을 사용하는 자료 구조를 사용하는 모든 시스템은 실패할 위험이 내재되어 있다. 이러한 자료 구조의 전체 목록을 도출하는 것은 사실상 불가능하지만, 유닉스 시간 문제를 가지고 있는 잘 알려진 자료 구조는 다음과 같다.

  • 아이노드에서 시간을 나타내기 위해 32비트를 사용하는 파일 시스템
  • 32비트 시간 필드를 가진 바이너리 파일 형식
  • 32비트 시간 필드를 가진 데이터베이스
  • `UNIX_TIMESTAMP()`와 유사한 명령을 가진 SQL과 같은 데이터베이스 쿼리 언어

3. 3. 임베디드 시스템

임베디드 시스템은 계산이나 진단 로깅에 날짜를 사용하는 경우 2038년 문제의 영향을 받을 가능성이 가장 높다.[6] 18~24개월 주기의 컴퓨터 시스템 기술 발전에도 불구하고, 임베디드 시스템은 구성 요소로 사용되는 기계의 수명 동안 사용하도록 설계되었다. 이러한 시스템 중 일부는 2038년에도 여전히 사용될 수 있으며, 소프트웨어를 업그레이드하는 것은 비실용적이거나 불가능할 수 있어 32비트 제한을 수정하려면 교체가 필요할 수 있다.

항공기, 자동차 등 많은 운송 시스템은 임베디드 시스템을 광범위하게 사용한다. 자동차에는 안티록 브레이크 시스템(ABS), 전자 제어 주행 안정화 장치(ESC/ESP), 미끄럼 방지 시스템(TCS), 자동 4륜 구동 등이, 항공기에는 관성 항법 장치, GPS 수신기 등이 사용될 수 있다.

그러나 모든 임베디드 시스템이 2038년 문제의 영향을 받는 것은 아니다. 날짜에 접근할 필요가 없는 시스템도 많으며, 날짜에 접근하더라도 절대적인 시간/날짜가 아닌 시간/날짜 간의 차이만 추적하는 시스템은 계산 특성상 큰 문제를 겪지 않을 것이다. 캘리포니아 대기 자원 위원회(CARB)와 같은 법률에 의해 규정된 표준에 기반한 자동차 진단이 그 예이다.[8]

3. 3. 1. 안드로이드 운영체제

임베디드 시스템은 라우터, 무선 접속 장치, IP 카메라 등 휴대폰 및 인터넷 지원 기기와 같이 정확한 시간과 날짜를 저장해야 하는 통신 장치에 쓰이며, 점점 더 유닉스 계열 운영 체제를 기반으로 한다. 예를 들어, 2038년 문제는 32비트 안드로이드를 실행하는 일부 장치가 해당 날짜로 시간이 변경되면 충돌하고 재시작되지 않게 한다.[7]

4. 해결책

2038년 문제에 대한 해결책은 현재의 CPU와 OS 조합으로는 간단하게 해결하기 어렵다. `time_t`의 정의를 변경하여 32비트 대신 64비트를 사용하면 소프트웨어 및 저장 장치 등에서 호환성 문제가 발생할 수 있다. `time_t`를 부호 없는 32비트 정수형으로 변경하면 2106년까지는 다룰 수 있지만, 음수를 다룰 수 없어 시간 차이를 계산하는 프로그램에서 문제가 발생한다.

64비트 시스템으로 전환하는 것이 근본적인 해결책이며, 이미 많은 운영체제가 64비트 `time_t`를 지원하고 있다. 64비트 정수형 체제에서는 이 문제를 약 3000억 년 정도 연기할 수 있다. 이는 태양의 수명보다 훨씬 길어 사실상 문제가 발생하지 않는다.

`time_t`를 64비트화할 수 없는 환경에서는 `time_t`를 부호 없는 32비트 정수형으로 사용하는 방법도 있다. 이 경우 2106년 2월 7일 6시 28분 15초(윤초 미고려)까지 표현 가능하여 2038년 문제는 피할 수 있지만, 2106년에는 문제가 발생하므로 임시방편에 가깝다.

각 운영체제 및 프로그래밍 언어별 해결 현황은 #운영체제별 64비트 time_t 지원 하위 섹션을 참조하라.

4. 1. 64비트 시스템으로 전환

현재의 CPU와 OS 조합으로는 이 문제에 대한 간단한 해결책이 없다. time_t의 정의를 변경하여 32비트 대신 64비트를 사용하도록 표현 범위를 확장할 수 있지만, 이는 소프트웨어, 저장 장치 등 시간의 이진 표현을 사용하는 모든 곳에서 바이너리 수준의 호환성 문제를 야기할 수 있다. time_t를 부호 없는 32비트 정수형으로 변경하면 2106년 2월 7일 06:28:15 UTC까지는 다룰 수 있지만, 프로그램이 시간 차이를 다루거나 상대적인 시간을 표현할 때 음수를 처리할 수 없어 문제가 발생한다.

ZIP 파일 포맷을 비롯한 많은 파일 포맷들이 `time_t`를 사용하고 있다는 점도 문제다.

macOS (Mac OS X 10.0) 에서는 `NSDate` 클래스에서 협정 세계시의 2001년 1월 1일 0시 정각을 에포크 타임으로 갱신하고[42][43], 경과 시간의 내부 표현으로서 배정밀도 부동소수점수를 사용하게 되었기 때문에[44], 이것들을 사용하는 한, 2038년에 관해서는 문제를 회피할 수 있다. 또한, macOS Mojave는 32비트 응용 프로그램을 동작시킬 수 있는 마지막 버전이 되었고, macOS Catalina에서는 시작할 수 없게 되었다[45].

32비트 버전의 Microsoft Windows (Win32) 에서는 내부 시간을 표현하는 데 64비트화된 `FILETIME` 구조체[46]를 사용하고 있으며, `time_t`를 사용하고 있는 것은 아니다. 따라서, Windows OS 측에 관해서는, 구 OS에 관한 일부 케이스를 제외하고[47], 32비트 버전이라도 2038년 문제는 발생하지 않는다[48]. 다만, Microsoft C/C++ (MS-C) 및 구 버전의 Microsoft Visual C++ (MSVC) 에서는 time_t는 32비트의 `long int`를 사용해서 정의되었기 때문에, 이러한 구 처리계의 C/C++ 런타임 라이브러리 (CRT) 를 이용하여 구축된 응용 소프트웨어나 DLL 등은 2038년 문제를 안고 있게 된다. x64 아키텍처의 64비트 버전 Windows OS 상에서는 WOW64 서브 시스템에 의해 x86 아키텍처용으로 구축된 32비트 응용 프로그램도 동작시킬 수 있지만, 구 32비트 응용 프로그램에서의 2038년 문제는, 설령 Windows OS를 64비트 버전으로 교체하더라도 회피할 수 없다. Microsoft Visual C++ 2005 이후에서는, 기본적으로 time_t는 `__time64_t`와 같고[49], 32비트 응용 프로그램이라도 time_t는 64비트화되기 때문에, 구 응용 프로그램을 새로운 처리계 및 런타임으로 재구축하면 2038년 문제를 회피할 수 있다.

네트워크 파일 시스템 버전 4는 2000년 12월부터 시간 필드를 `struct nfstime4 {int64_t seconds; uint32_t nseconds;}`로 정의했다.[25] 버전 3은 `struct nfstime3 {uint32 seconds; uint32 nseconds;}`로 부호 없는 32비트 값을 지원한다.[26] 초 필드의 0보다 큰 값은 1970년 1월 1일 0시 이후의 날짜를 나타낸다. 초 필드의 0보다 작은 값은 1970년 1월 1일 0시 이전의 날짜를 나타낸다. 두 경우 모두, nseconds (나노초) 필드는 최종 시간 표현을 위해 초 필드에 추가된다.

ext4 파일 시스템은 128바이트보다 큰 inode 크기를 사용할 때, 타임스탬프의 나노초 부분을 위해 30비트가 사용되고, 나머지 2비트는 타임스탬프 범위를 2446년까지 확장하는 추가 32비트 필드를 타임스탬프당 갖는다.[27]

XFS 파일 시스템은 리눅스 5.10부터 선택적 "빅 타임스탬프" 기능을 통해 타임스탬프 범위를 2486년까지 확장한다.[28]

4. 1. 1. 운영체제별 64비트 time_t 지원

64비트 아키텍처를 사용하는 대부분의 운영 체제는 이미 `time_t`에 64비트 정수를 사용하고 있다. 이러한 아키텍처로의 이전은 이미 진행 중이며, 많은 사람들은 2038년 이전에 완료될 것으로 예상한다. 그러나 2012년 기준으로 수억 대의 32비트 시스템이 있으며, 많은 수가 임베디드 시스템에 내장되어 있는데, 이 모두가 2038년까지 교체될 수 있을지는 불분명하다.

64비트 정수형 체제에서는 이 문제를 약 3000억 년 정도 연기시킬 수 있다.

다음은 주요 운영체제별 64비트 `time_t` 지원 현황이다.

운영체제버전32비트 `time_t` 지원64비트 `time_t` 지원비고
루비1.9.2 (2010년 8월 18일)O64비트 정수형으로 시간을 저장하며, 2038년 문제 해결[17][18]
NetBSD6.0 (2012년 10월)XO바이너리 호환성 계층을 통해 32비트 `time_t` 애플리케이션 지원[19]
OpenBSD5.5 (2014년 5월)XO바이너리 호환성 계층 없음[20]
리눅스5.6 (2020년)OO32비트 아키텍처에서도 64비트 `time_t` 지원[22]
GNU C Library2.34 (2021년 8월)OO전처리기 매크로 `_TIME_BITS`를 `64`로 정의하여 활성화[23]
FreeBSDi386 제외, 부호 있는 32비트 `time_t` 사용O
리눅스용 x32 ABIO32비트 주소를 가진 프로그램에 대한 환경 정의, 프로세서는 64비트 모드로 실행[21]
OpenVMS32비트 정수를 사용[30]O31086년 7월 31일까지 타임스탬프를 지원하며,[29] C 런타임 라이브러리(CRTL)는 2106년 2월 7일까지 확장[31]
PostgreSQL7.2 (2002년 2월 4일)O"시간대 없는 타임스탬프" 데이터 형식에 64비트 정수 사용[32]
MySQL8.0.28 (2022년 1월)O64비트 버전의 리눅스, macOS 및 윈도우에서 64비트 값 처리[33][34]
MariaDB11.5.1 (2024년 5월)O64비트 버전의 리눅스, macOS 및 윈도우에서 부호 없는 32비트 값 처리[36]
Visual C++2005O`_USE_32BIT_TIME_T` 전처리기 매크로가 정의되지 않는 한 64비트 `time_t` 사용[37]
macOSO



윈도우는 내부적으로 시간을 1601년 1월 1일 이후의 100나노초 간격의 수로 64비트 부호 있는 정수로 추적하므로, 윈도우 API 자체는 2038년 문제의 영향을 받지 않으며, 30,828년까지 오버플로우되지 않는다.[38]

4. 2. 기타 해결책

현재의 CPU와 OS 조합으로는 이 문제를 간단히 해결하기 어렵다. 32비트 대신 64비트를 사용하도록 `time_t`의 정의를 변경하면 소프트웨어 및 저장 장치 등에서 호환성 문제가 발생할 수 있다. `time_t`를 부호 없는 32비트 정수형으로 변경하면 2106년까지는 다룰 수 있지만, 음수를 다룰 수 없어 시간 차이를 계산하는 프로그램에서 문제가 발생한다.

64비트 아키텍처를 사용하는 대부분의 운영 체제는 이미 `time_t`에 64비트 정수를 사용하고 있다. 많은 사람들이 2038년 전에 64비트 아키텍처로의 전환이 완료될 것으로 예상하지만, 2012년 기준으로 수억 대의 32비트 시스템, 특히 임베디드 시스템이 여전히 사용 중이며, 이들이 모두 교체될지는 불분명하다. 또한 `time_t`는 ZIP 파일 포맷 등 많은 파일 포맷에 사용되고 있다.

64비트 정수형 체제에서는 이 문제를 약 3000억 년 정도 연기할 수 있다. 그러나 이는 태양의 수명보다 훨씬 길기 때문에 지구상의 컴퓨터에서는 문제가 발생하지 않는다.

몇몇 프로그래밍 언어 및 운영 체제는 이미 2038년 문제에 대한 해결책을 도입했다.

  • 루비 버전 1.9.2부터 32비트 시스템에서도 64비트 정수형으로 시간을 저장한다.[17][18]
  • NetBSD 버전 6.0부터 32비트 및 64비트 아키텍처 모두에 64비트 `time_t`를 사용한다. 이전 버전과의 호환성을 위해 32비트 `time_t`를 사용하는 애플리케이션도 지원하지만, 이 경우 여전히 2038년 문제가 발생한다.[19]
  • OpenBSD 버전 5.5부터 32비트 및 64비트 아키텍처 모두에 64비트 `time_t`를 사용한다. NetBSD와 달리 바이너리 호환성 계층이 없어, 32비트 `time_t`를 사용하는 애플리케이션은 작동하지 않을 수 있다.[20]
  • 리눅스는 원래 64비트 아키텍처에서만 64비트 `time_t`를 사용했지만, 버전 5.6부터 32비트 아키텍처에서도 지원한다. 이는 주로 임베디드 리눅스 시스템을 위한 것이다.[22]
  • GNU C Library 버전 2.34부터 32비트 플랫폼에서 64비트 `time_t`를 사용할 수 있도록 지원한다. 소스 코드를 컴파일할 때 전처리기 매크로를 정의하여 활성화할 수 있다.[23]
  • FreeBSD는 32비트 i386을 제외한 모든 32비트 및 64비트 아키텍처에 64비트 `time_t`를 사용한다.[24]
  • x32 ABI는 64비트 `time_t`를 사용한다.[21]
  • 네트워크 파일 시스템 버전 4는 2000년 12월부터 시간 필드에 64비트 정수를 사용한다.[25]
  • ext4 파일 시스템은 타임스탬프 범위를 2446년까지 확장하는 기능을 제공한다.[27]
  • XFS 파일 시스템은 리눅스 5.10부터 타임스탬프 범위를 2486년까지 확장하는 기능을 제공한다.[28]
  • OpenVMS는 31086년까지 타임스탬프를 지원하지만, C 런타임 라이브러리(CRTL)는 `time_t`에 32비트 정수를 사용한다. Y2K 호환성 작업의 일환으로 CRTL은 부호 없는 32비트 정수를 사용하도록 수정되어 `time_t`의 범위를 2106년까지 확장했다.[31]
  • PostgreSQL은 버전 7.2부터 "시간대 없는 타임스탬프" 데이터 형식에 64비트 정수를 사용한다.[32]
  • MySQL 8.0.28부터 64비트 값을 처리하는 함수를 지원한다.[33][34] 이전 버전에서는 2038년 이후 0을 반환한다.[35]
  • MariaDB 11.5.1부터 64비트 버전의 리눅스, macOS 및 윈도우에서 부호 없는 32비트 값을 처리하여 범위를 2106년까지 확장한다.[36]
  • Visual C++ 2005부터 64비트 `time_t`를 사용한다.[37] 그러나 윈도우 API 자체는 2038년 문제의 영향을 받지 않는다.[38]


`time_t` 형을 부호 있는 64비트 정수형 (일반적으로 '''`long long int` 형''')으로 변경하면 상한은 (263 − 1)이 되어 서기 3000억 년까지 사용할 수 있어 사실상 문제가 발생하지 않는다.

`time_t`를 64비트화할 수 없는 환경에서는 `time_t`를 부호 없는 32비트 정수형 (일반적으로 '''`unsigned long int` 형''')으로 하는 방법도 있다. 이 경우, 상한은 (232 − 1)가 되어, 2106년 2월 7일 6시 28분 15초 (윤초를 고려하지 않는 경우)까지 표현 가능하게 된다.

macOS (Mac OS X 10.0)에서는 `NSDate` 클래스에서 협정 세계시의 2001년 1월 1일 0시 정각을 에포크 타임으로 갱신하고,[42][43] 경과 시간의 내부 표현으로서 배정밀도 부동소수점수를 사용하게 되었기 때문에,[44] 2038년 문제를 회피할 수 있다. 또한, macOS Mojave는 32비트 응용 프로그램을 동작시킬 수 있는 마지막 버전이 되었고, macOS Catalina에서는 시작할 수 없게 되었다.[45]

32비트 버전의 Microsoft Windows (Win32)에서는 내부 시간을 표현하는 데 64비트화된 `FILETIME` 구조체[46]를 사용하고 있으며, `time_t`를 사용하고 있는 것은 아니다. 따라서, Windows OS 측에서는 2038년 문제가 발생하지 않는다.[48] 다만, Microsoft C/C++ (MS-C) 및 구 버전의 Microsoft Visual C++ (MSVC)에서는 `time_t`는 32비트의 `long int`를 사용해서 정의되었기 때문에, 이러한 구 처리계의 C/C++ 런타임 라이브러리 (CRT)를 이용하여 구축된 응용 소프트웨어나 DLL 등은 2038년 문제를 안고 있게 된다. x64 아키텍처의 64비트 버전 Windows OS 상에서는 WOW64 서브 시스템에 의해 x86 아키텍처용으로 구축된 32비트 응용 프로그램도 동작시킬 수 있지만, 구 32비트 응용 프로그램에서의 2038년 문제는 회피할 수 없다. Microsoft Visual C++ 2005 이후에서는, 기본적으로 `time_t`는 `__time64_t`와 같고,[49] 32비트 응용 프로그램이라도 `time_t`는 64비트화되기 때문에, 구 응용 프로그램을 새로운 처리계 및 런타임으로 재구축하면 2038년 문제를 회피할 수 있다.

5. 알려진 문제 사례

2006년 5월에 발생한 AOLserver 소프트웨어 문제는 최초로 나타난 2038년 문제의 예로 알려져 있다. AOLserver는 데이터베이스 연결 지속 시간을 10억 초로 지정하여 '절대로 연결이 끊기지 않음'을 나타내는 경우가 있었는데, 2006년 5월 13일 01:27:28 UTC에서 10억 초가 지난 시간은 `time_t`로 표시할 수 없었다. 따라서 이 시점부터 지속 시간이 과거의 시간으로 계산되어 소프트웨어에 문제를 일으켰다.[52]

2006년 5월, AOL서버 소프트웨어에서 2038년 문제(Y2038)의 초기 징후가 나타났다는 보고가 나왔다. AOL 서버는 "절대" 시간 초과가 되지 않아야 하는 데이터베이스 요청을 처리하기 위해 임시변통으로 설계되었다. 이 특별한 경우를 처리하기 위해 미래의 임의의 시간 초과 날짜를 지정했는데, 기본 구성에서는 요청이 최대 10억 초 후에 시간 초과되도록 지정했다. 그러나 2038년 컷오프 날짜로부터 10억 초 전은 2006년 5월 13일 01:27:28 UTC이므로, 이 시간 이후에 전송된 요청은 컷오프를 초과하는 시간 초과 날짜를 초래하게 된다. 이로 인해 시간 초과 계산이 오버플로되어 실제로는 과거의 날짜를 반환하여 소프트웨어가 충돌했다. 이 문제가 발견되었을 때, AOL서버 운영자는 구성 파일을 편집하여 시간 초과 값을 더 낮게 설정해야 했다.[9][10]

시간 a와 시간 b의 정확히 중간 시간을 구할 때, 각 유닉스 시간을 Ta와 Tb라고 하면, (Ta + Tb) / 2로 계산할 수 있다. 하지만 2038년 문제의 절반 이후가 경과했을 경우 Ta + Tb 계산에서 오버플로가 발생하여 잘못된 결과가 나올 수 있다. 이는 2004년 1월 10일 13시 37분 4초 이후가 이에 해당한다. 2004년 1월 10일 또는 11일에 이 사례로 추정되는 보고가 있었다.[50] 이 문제를 피하기 위해서는 다음과 같은 계산 방법을 사용할 수 있다.

# 시간의 차이를 계산한다: 시간 b에서 시간 a를 빼서 그 차이를 구한다.

# 차이의 절반을 구한다: 구한 차이를 2로 나눈다.

# 시간 a에 더한다: 시간 a에 차이의 절반을 더하여 중간 시간을 구한다. 이 방법을 수식으로 나타내면 다음과 같다: 중간 시간 = ''Ta'' + (''Tb'' − ''Ta'')/2

6. 유사 문제

2000년 문제는 애플리케이션 수준에서 수정이 가능했지만, 2038년 문제는 현재 보급되어 있는 C 언어 처리계나 OS의 API와 같은 시스템의 깊은 층에 잠재된 문제이기 때문에 2000년 문제보다 심각하다는 지적이 있다.[41]


  • 2001년 9월 9일 문제는 2001년 9월 9일에 time_t형의 값이 9억 초에서 10억 초로 자릿수가 증가함에 따라 발생하는 문제이다. time_t형의 값을 문자열(사전 순)로 정렬했기 때문에 "9억 > 10억"으로 판단되어 항목의 신구(新舊)가 올바르게 판단되지 않아 새롭게 만들어진 항목이 표시되지 않거나, 오래된 것으로 간주되어 삭제되는 등의 문제가 발생했다.
  • NTP 등, 1900년 1월 1일부터의 누적 초 수로 시간을 표현하는 시스템도 있으며, 부호 없는 32비트 값이 2036년 2월 7일 6시 28분 15초 (UTC)를 초과하면 오버플로가 발생하여 문제가 발생한다(→2036년 문제). SNTPv4를 규정한 문서에는 최상위 비트가 0인 경우 시각이 2036년부터 2104년 사이인 것으로 간주하여 2036년 2월 7일 6시 28분 16초 (UTC)를 기점으로 계산함으로써 2036년 문제를 회피하는 방법이 기술되어 있다.
  • 2038년 4월 23일 문제 - 율리우스일을 내부 날짜 표현에 사용하는 것 중, 기준일(그레고리력 1858년 11월 17일 정오)부터의 수정 율리우스일(MJD)을 사용하고, 16비트로 처리하는 시스템에서는, 날짜 수가 16비트에서 넘치기 때문에 문제가 발생한다.

참조

[1] 웹사이트 Year 2038 Problem Website https://theyear2038p[...] 2024-09-19
[2] 웹사이트 The end of an Era https://www.linaro.o[...] Linaro 2020-02-06
[3] 뉴스 Digital 'Epochalypse' Could Bring World to Grinding Halt https://www.tomsguid[...] 2017-07-28
[4] 웹사이트 Epoch Time https://www.unixtuto[...] 2019-03-15
[5] 서적 Code quality: the open source perspective https://books.google[...] Adobe Press
[6] 뉴스 Is the Year 2038 problem the new Y2K bug? https://www.theguard[...] 2014-12-17
[7] 웹사이트 ZTE Blade running Android 2.2 has 2038 problems https://issuetracker[...]
[8] 웹사이트 ARB Test Methods / Procedures http://www.arb.ca.go[...] California Air Resources Board
[9] 웹사이트 The Future Lies Ahead http://substitute.li[...] 2006-06-28
[10] Webarchive Weird "memory leak" problem in AOLserver 3.4.2/3.x http://www.mail-arch[...] 2010-01-04
[11] 웹사이트 DRAFT: Y2038 Proofness Design https://sourceware.o[...]
[12] 웹사이트 When does the 64-bit Unix time_t really end? https://ximalas.info[...]
[13] 웹사이트 The End of Time http://stablecross.c[...] 2010-04-17
[14] 웹사이트 Unununium Time http://unununium.org[...]
[15] 웹사이트 Java API documentation for System.currentTimeMillis() https://docs.oracle.[...]
[16] 웹사이트 TAI64 http://cr.yp.to/libt[...]
[17] 웹사이트 Ruby 1.9.2 is released https://www.ruby-lan[...] 2010-08-18
[18] 웹사이트 time.c: use 64bit arithmetic even on platforms with 32bit VALUE https://github.com/r[...]
[19] 웹사이트 Announcing NetBSD 6.0 https://www.netbsd.o[...] 2012-10-17
[20] 웹사이트 OpenBSD 5.5 released (May 1, 2014) http://www.openbsd.o[...] 2014-05-01
[21] 웹사이트 Pondering 2038 https://lwn.net/Arti[...] 2013-08-14
[22] 웹사이트 LKML: Arnd Bergmann: [GIT PULL] y2038: core, driver and file system changes https://lkml.org/lkm[...] 2020-01-30
[23] 웹사이트 The GNU C Library version 2.34 is now available https://sourceware.o[...] 2021-08-02
[24] 웹사이트 arch https://www.freebsd.[...]
[25] 간행물 Network File System (NFS) Version 4 Protocol 2015-03
[26] 웹사이트 NFS Version 3 Protocol Specification https://datatracker.[...] 1995-06
[27] 웹사이트 ext4 Data Structures and Algorithms https://www.kernel.o[...]
[28] 웹사이트 XFS File-System With Linux 5.10 Punts Year 2038 Problem To The Year 2486 https://www.phoronix[...] 2020-10-15
[29] 웹사이트 Why is Wednesday, November 17, 1858 the base time for OpenVMS (VAX VMS)? https://www.slac.sta[...] 1997-07-24
[30] 웹사이트 VSI C Run-Time Library Reference Manual for OpenVMS Systems https://vmssoftware.[...] VSI 2020-11
[31] 웹사이트 OpenVMS and the year 2038 https://www.zx.net.n[...] HP
[32] 웹사이트 PostgreSQL Release 7.2 https://www.postgres[...] 2012-01
[33] 웹사이트 What Is New in MySQL 8.0 https://dev.mysql.co[...]
[34] 웹사이트 Changes in MySQL 8.0.28 (2022-01-18, General Availability) https://dev.mysql.co[...]
[35] 웹사이트 MySQL Bugs: #12654: 64-bit unix timestamp is not supported in MySQL functions https://bugs.mysql.c[...]
[36] 웹사이트 MariaDB 11.5.1 Release Notes https://mariadb.com/[...]
[37] 웹사이트 Microsoft C/C++ change history 2003 - 2015 https://learn.micros[...] 2023-05-25
[38] 웹사이트 About Time - Win32 apps https://learn.micros[...] 2021-01-07
[39] 문서
[40] 뉴스 コンピュータの“西暦2038年問題”発生、早くも日本を揺るがす https://xtech.nikkei[...] 日経コンピュータ 2004-02-02
[41] 웹사이트 2025年問題の次は2038年問題!コンピュータの暦問題を探る(後編) https://www.change-m[...] 2018-11-20
[42] Apple Docs NSDate - Foundation | Apple Developer Documentation https://developer.ap[...]
[43] Apple Docs Date Representations https://developer.ap[...]
[44] Apple Docs NSTimeInterval | Apple Developer Documentation https://developer.ap[...]
[45] Apple Support 32 ビット App と macOS High Sierra 10.13.4 以降の互換性 - Apple サポート https://support.appl[...]
[46] Microsoft Docs FILETIME (minwinbase.h) - Win32 apps | Microsoft Docs https://docs.microso[...]
[47] Internet Archive システム日付が 2038 年以降に設定されていると、Windows XP のセットアップが途中で停止する場合がある https://web.archive.[...]
[48] Microsoft Docs Another look at the year 2038 problem | Microsoft Docs https://docs.microso[...]
[49] Microsoft Docs Time Management | Microsoft Docs https://docs.microso[...]
[50] 뉴스 「西暦2038年問題」でトラブル相次ぐ https://xtech.nikkei[...] 日経コンピュータ 2004-04-01
[51] 웹사이트 http://www.merlyn.de[...] 2015-09-07
[52] 메일링 리스트 AOLServer 버그 관련 메일링 리스트 글타래 http://www.mail-arch[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com